program SAPnote;

include <core.vhs>
include <shell.vhs>
include <netutil.vhs>
include <database.vhs>

import core::*;
import core::Pattern::*;
import core::Logging::*;
import netutil::*;
import database::*;
import database::CSV::*;

const dbname='output/sap.csv';
const dbconf='ID,Component,Release,From,To';

function insert_sap(db, ...) CSV::insert(db, ...)

function downloadAllSAPnote(input='notelist.tab', database) {
	var pat=@'^(\d+).+?\n';
	var link=@'https://websmp230.sap-ag.de/sap(bD1lbiZjPTAwMQ==)/bc/bsp/spn/sapnotes/index2.htm?numm=000';
	var total = 0;
	var fail = 0;
	var outfunc = function(data) {
		//insert_sap(database, data.id, data.component, data.release, data.from, data.to);
		database.writeCsvLine([data.id, data.component, data.release, data.from, data.to]);
	}
	
	log('Start downloading SAP note');
	var parseNoteListPat = pattern<DataPart>($dataPattern=pat, $minOccur=0, $maxOccur=INFINITY) {
		total++;
		var id = this[1] + '';
		log('Download note %s...', id); 
		var f = download(link + id, timeout=500000, cacheFile='webcache/sap' + id + '.html');
		if (f == null) {
			log_warning('Unable to download note %s.');
			fail++;
		}
		else {
			var ip = new SequenceStream(f, 4096);
			ParseSAPNote(input=ip, id=id, outfunc=outfunc);
			ip.close();
		}
	}
	parseNoteListPat(input = new SequenceStream(input, 4096));
	log('Download completed. %d notes total, %d notes fail', total, fail);
	
}

pattern ParseSAPNote(id, outfunc) {
	locate(@'<p.+?>Affected Releases</p>'); // look for Affected Releases Section
	locate('<table'); // skip the outline table of ReleaseTable
	locate('<table'); // locate the actual ReleaseTable
	locate('</tr>'); // skip table header
	locate_end('</table>'); // locate the table end
	
	var extractTableRow = pattern(outfunc, $minOccur=0, $maxOccur=INFINITY) {
		locate_end('</tr>');
		var extractTableColumn = pattern<DataPart>($dataPattern=@'<td.+?<span.+?>(.+?)</span>') this[1]; 
		var entry = struct {id=id, component = extractTableColumn(), release=extractTableColumn(), from=extractTableColumn(), to=extractTableColumn() };
		outfunc?(entry);
	}
	extractTableRow(outfunc);
}


function main() {
	Logging::configureLog("download-sapnote.log");
	netutil::setExpiredSecPeriod(SEC_PER_MONTH);
	setPasswordAuthentication('s0008754131', 'ne55una');
	
	var db=openDatabase(dbname, dbconf);
	downloadAllSAPnote(database=db);
	closeDatabase(db);
	//download('https://websmp230.sap-ag.de/sap(bD1lbiZjPTAwMQ==)/bc/bsp/spn/sapnotes/index2.htm?numm=0001727640');
	//download('https://websmp130.sap-ag.de/sap(bD1lbiZjPTAwMQ==)/bc/bsp/spn/sapnotes/index2.htm?numm=0001690738');
}
